package com.baomidou.kisso.web.interceptor;

import com.baomidou.kisso.SSOHelper;
import com.baomidou.kisso.annotation.Action;
import com.baomidou.kisso.annotation.Login;
import com.baomidou.kisso.common.SSOConstants;
import com.baomidou.kisso.common.util.HttpUtil;
import com.baomidou.kisso.security.token.SSOToken;
import com.baomidou.kisso.web.handler.KissoDefaultHandler;
import com.baomidou.kisso.web.handler.SSOHandlerInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @author : fuminwang
 * @Description :
 * @CreateDate : 2018/01/03 13:27
 */
@Component
public class SSOYmInterceptor implements HandlerInterceptor {

    public static final Logger logger = LoggerFactory.getLogger(SSOYmInterceptor.class);

    private SSOHandlerInterceptor handlerInterceptor;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        /**
         * 处理 Controller 方法
         * <p>
         * 判断 handler 是否为 HandlerMethod 实例
         * </p>
         */
        if (o instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) o;
            Method method = handlerMethod.getMethod();
            Login login = method.getAnnotation(Login.class);
            if (login != null) {
                if (login.action() == Action.Skip) {
                    /**
                     * 忽略拦截
                     */
                    logger.info("url is login:{}" + login.action().getDesc());
                    return true;
                }
            }

            /**
             * 正常执行
             */
            SSOToken ssoToken = SSOHelper.getSSOToken(httpServletRequest);
            if (ssoToken == null) {
                if (HttpUtil.isAjax(httpServletRequest)) {
                    /*
                     * Handler 处理 AJAX 请求
					 */
                    this.getHandlerInterceptor().preTokenIsNullAjax(httpServletRequest, httpServletResponse);
                    logger.info("处理 AJAX 请求");
                    return false;
                } else {
					/*
					 * token 为空，调用 Handler 处理
					 * 返回 true 继续执行，清理登录状态并重定向至登录界面
					 */
                    if (this.getHandlerInterceptor().preTokenIsNull(httpServletRequest, httpServletResponse)) {
                        logger.info("cookie token 为空,清理登录状态并重定向至登录界面");
                        SSOHelper.clearRedirectLogin(httpServletRequest, httpServletResponse);
                    }
                    return false;
                }
            } else {
				/*
				 * 正常请求，request 设置 token 减少二次解密
				 */
                httpServletRequest.setAttribute(SSOConstants.SSO_TOKEN_ATTR, ssoToken);
            }
        }

        /**
         * 通过拦截
         */
        return true;

    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println(">>>SSOYmInterceptor>>>>>>>请求处理之后进行调用，但是在视图被渲染之前（Controller方法调用之后）");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println(">>>SSOYmInterceptor>>>>>>>在整个请求结束之后被调用，也就是在DispatcherServlet 渲染了对应的视图之后执行（主要是用于进行资源清理工作）");
    }


    public SSOHandlerInterceptor getHandlerInterceptor() {
        if (handlerInterceptor == null) {
            return KissoDefaultHandler.getInstance();
        }
        return handlerInterceptor;
    }

    public void setHandlerInterceptor(SSOHandlerInterceptor handlerInterceptor) {
        this.handlerInterceptor = handlerInterceptor;
    }
}
